package edu.lingnan.lmlibrary.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import edu.lingnan.lmlibrary.common.JSONResult;
import edu.lingnan.lmlibrary.dto.BookingSeatInfo;
import edu.lingnan.lmlibrary.dto.FloorSeats;
import edu.lingnan.lmlibrary.entity.Booking;
import edu.lingnan.lmlibrary.entity.Desk;
import edu.lingnan.lmlibrary.entity.Floor;
import edu.lingnan.lmlibrary.entity.Seat;
import edu.lingnan.lmlibrary.mapper.BookingMapper;
import edu.lingnan.lmlibrary.mapper.DeskMapper;
import edu.lingnan.lmlibrary.mapper.FloorMapper;
import edu.lingnan.lmlibrary.mapper.SeatMapper;
import edu.lingnan.lmlibrary.service.SeatService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import edu.lingnan.lmlibrary.util.HttpRequestRouteStudentInfo;
import net.minidev.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 张晓航
 * @since 2022-02-26
 */
@Service
@Transactional
public class SeatServiceImpl extends ServiceImpl<SeatMapper, Seat> implements SeatService {

    @Resource
    private FloorMapper floorMapper;

    @Resource
    private DeskMapper deskMapper;

    @Resource
    private SeatMapper seatMapper;

    @Resource
    private BookingMapper bookingMapper;

    @Override
    public int insertSeatsByFloorAndDeskAndSeatCounts(String fNum, Integer deskCount, ArrayList<Integer> seatCounts) {
        /**
         * 步骤：
         * ①先插入一条楼层数据,名称用参数中的fNum，数量：seatCounts之和，能用座位数：seatCounts之和，f_status=1
         * ②插入桌子数据，每插入一条就插入对应的座位数
         */
        int flag = 1;

        try {
            Floor floor = new Floor();
            int seatAll = 0;
            for (int i = 0; i < seatCounts.size(); i++) {
                seatAll += seatCounts.get(i);
            }
            floor.setFStatus("1").setFNum(fNum).setFCount(seatAll).setFCanables(seatAll);
            int insert = floorMapper.insert(floor);

            for (int i = 0; i < deskCount; i++) {
                //插入桌子数据
                Desk desk = new Desk();
                desk.setSeatCount(seatCounts.get(i));
                desk.setFId(floor.getFId());
                desk.setDName(""+(i+1));
                int insert1 = deskMapper.insert(desk);

                //插入座位
                for (int j = 0; j < seatCounts.get(i); j++) {
                    Seat seat = new Seat();
                    seat.setSeatStatus("1").setDId(desk.getDId()).setSeatNum(j+1);
                    seatMapper.insert(seat);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            flag = 0;
            return flag;
        }
        return flag;
    }

    @Override
    public JSONResult<List<FloorSeats>> getDeskAndSeatCountsByFloorId(Integer fId) {
        /*
        * 步骤
        * ①得到楼层名称
        * ②得到该楼层对应的桌子列表
        * ③通过该桌子列表，能得到每个桌子对应的座位信息
        * */
        JSONResult<List<FloorSeats>> result = new JSONResult<>();
        ArrayList<FloorSeats> floorSeats = new ArrayList<>();
        Floor floor = floorMapper.selectById(fId);
        if(floor == null)
        {
            result.setCode(201);
            result.setData(null).setMessage("楼层不存在");

            return result ;
        }
        Desk desk = new Desk();
        desk.setFId(fId);
        QueryWrapper<Desk> wrapper = new QueryWrapper<>();
        wrapper.eq("f_id",fId);
        //根据楼层编号查出桌子列表
        List<Desk> desks = deskMapper.selectList(wrapper);
        for (Desk desk1 : desks) {
            FloorSeats floorSeats1 = new FloorSeats();
            floorSeats1.setFNum(floor.getFNum());
            floorSeats1.setDName(desk1.getDName());
//            根据桌子编号查出座位列表
            QueryWrapper<Seat> seatQueryWrapper = new QueryWrapper<>();
            seatQueryWrapper.eq("d_id",desk1.getDId());
            List<Seat> seats = seatMapper.selectList(seatQueryWrapper);
            floorSeats1.setSeatArrays(seats);

            floorSeats.add(floorSeats1);
        }
        result.setCode(200);
        result.setData(floorSeats);
        result.setMessage("操作成功");

        return result;
    }

    /*
    * 1，选座位思路
    前端传来座位编号：seat_id,学生学号：s_id
    ①判断该学生是否存在
    ②判断该学生是否有正在生效的座位，因为一个人同一时间段只能预约一个座位
    ③判断该座位状态，能否预约
    ④如果能预约，则生成一条预约记录，改变该座位状态，改变楼层能预约的座位数
    * */
    @Override
    public JSONResult<BookingSeatInfo> bookingSeatBySeatIdAndSid(Integer seatId, String sId, RestTemplate restTemplate) {
//         ①判断该学生是否存在
        if(seatId == null)
        {
            return new JSONResult<>(201,"座位号不能为空",null);
        }
        if(sId == null)
        {
            return new JSONResult<>(201,"学号不能为空",null);
        }
        HashMap<String, String> map = new HashMap<>();
        map.put("no",sId.trim());
        ResponseEntity<JSONObject> responseEntity = HttpRequestRouteStudentInfo.httpRequestRouteStudentInfo(
                "http://120.77.247.146:1281/student-all-Info-by-id",
                "get",
                map,
                restTemplate
        );
        JSONObject body = responseEntity.getBody();
        Integer integer = (Integer) body.get("code");
        if(integer.intValue() != 200)
        {
            return new JSONResult<BookingSeatInfo>(201,"该学生不存在",null);
        }
//            ②判断该学生是否有正在生效的座位，因为一个人同一时间段只能预约一个座位
        QueryWrapper<Booking> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("s_id",sId.trim());
        queryWrapper.eq("b_useful","1");//1代表正在生效的预约记录
        List<Booking> bookings = bookingMapper.selectList(queryWrapper);
        if(bookings.size() != 0)
        {
            return new JSONResult<BookingSeatInfo>(201,"该学生已有预约记录",null);
        }
        Seat seat;
        Floor floor;
        Desk desk;
        //使用同步锁，防止同一个座位被选中
        synchronized (this){
            //        ③判断该座位状态，能否预约
            seat = seatMapper.selectById(seatId);
            if(seat ==null || seat.getSeatStatus().equals("0"))
            {
                return new JSONResult<BookingSeatInfo>(201,"该座位不存在或者已被预约",null);
            }

//        ④如果能预约，则生成一条预约记录，改变该座位状态，改变楼层能预约的座位数
            seat.setSeatStatus("0");
            int i = seatMapper.updateById(seat);
            Booking booking = new Booking();
            SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            String format1 = format.format(new Date());
            Booking booking1 = booking.setSeatId(seatId).setBStartTime(format1)
                    .setBEndTime(format1)
                    .setSId(sId.trim())
                    .setBUseful("1");
            int insert = bookingMapper.insert(booking1);
            desk = deskMapper.selectById(seat.getDId());
            floor = floorMapper.selectById(desk.getFId());
            floor.setFCanables(floor.getFCanables()-1);
            int j = floorMapper.updateById(floor);
        }

        BookingSeatInfo seatInfo = new BookingSeatInfo();
        seatInfo.setSeatNum(seat.getSeatNum()).
                setFNum(floor.getFNum()).
                setDName(desk.getDName()).
                setSId(sId.trim());
        return new JSONResult<BookingSeatInfo>(200,"预约成功",seatInfo);
    }
}
